// SPDX-FileCopyrightText: Copyright 2025-2025 深圳市同心圆网络有限公司
// SPDX-License-Identifier: Apache-2.0

package roadmap_data_api_serv

import (
	"context"
	"time"

	"gitcode.com/lvupclub/lvup-api/dao"
	"gitcode.com/lvupclub/lvup-api/dao/roadmap_dao"
	"gitcode.com/lvupclub/proto-gen-go.git/src/roadmap_data_api"
)

func (apiImpl *RoadmapDataApiImpl) AddEdge(ctx context.Context, req *roadmap_data_api.AddEdgeRequest) (*roadmap_data_api.AddEdgeResponse, error) {
	sessItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &roadmap_data_api.AddEdgeResponse{
			Code:   roadmap_data_api.AddEdgeResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	//获取路线图信息
	roadmapItem, err := roadmap_dao.RoadmapInfoDao.Get(ctx, req.RoadmapId)
	if err != nil {
		return &roadmap_data_api.AddEdgeResponse{
			Code:   roadmap_data_api.AddEdgeResponse_CODE_NO_ROADMAP,
			ErrMsg: "成长路线图不存在",
		}, nil
	}
	//只有路线图owner可以修改
	if roadmapItem.OwnerUserId != sessItem.UserId {
		return &roadmap_data_api.AddEdgeResponse{
			Code:   roadmap_data_api.AddEdgeResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	//检查节点是否存在
	exist, err := roadmap_dao.NodeInfoDao.Exist(ctx, req.RoadmapId, req.EdgeKey.FromNodeId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &roadmap_data_api.AddEdgeResponse{
			Code:   roadmap_data_api.AddEdgeResponse_CODE_NO_NODE,
			ErrMsg: "成长路线图节点不存在",
		}, nil
	}
	exist, err = roadmap_dao.NodeInfoDao.Exist(ctx, req.RoadmapId, req.EdgeKey.ToNodeId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &roadmap_data_api.AddEdgeResponse{
			Code:   roadmap_data_api.AddEdgeResponse_CODE_NO_NODE,
			ErrMsg: "成长路线图节点不存在",
		}, nil
	}

	nowTime := time.Now().UnixMilli()

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx context.Context) (interface{}, error) {
		err = roadmap_dao.EdgeInfoDao.Insert(sessCtx, &roadmap_dao.EdgeInfoDbItem{
			RoadmapId: req.RoadmapId,
			EdgeKey: roadmap_dao.EdgeKeyDbItem{
				FromNodeId: req.EdgeKey.FromNodeId,
				FromHandle: req.EdgeKey.FromHandle,
				ToNodeId:   req.EdgeKey.ToNodeId,
				ToHandle:   req.EdgeKey.ToHandle,
			},
			BasicInfo: roadmap_dao.BasicEdgeInfoDbItem{
				EdgeType:      req.BasicInfo.EdgeType,
				HasStartArrow: req.BasicInfo.HasStartArrow,
				HasEndArrow:   req.BasicInfo.HasEndArrow,
				Label:         req.BasicInfo.Label,
			},
			CreateTime: nowTime,
			UpdateTime: nowTime,
		})
		if err != nil {
			return nil, err
		}
		return &roadmap_data_api.AddEdgeResponse{
			Code: roadmap_data_api.AddEdgeResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*roadmap_data_api.AddEdgeResponse), nil
}

func (apiImpl *RoadmapDataApiImpl) UpdateEdge(ctx context.Context, req *roadmap_data_api.UpdateEdgeRequest) (*roadmap_data_api.UpdateEdgeResponse, error) {
	sessItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &roadmap_data_api.UpdateEdgeResponse{
			Code:   roadmap_data_api.UpdateEdgeResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	//获取路线图信息
	roadmapItem, err := roadmap_dao.RoadmapInfoDao.Get(ctx, req.RoadmapId)
	if err != nil {
		return &roadmap_data_api.UpdateEdgeResponse{
			Code:   roadmap_data_api.UpdateEdgeResponse_CODE_NO_ROADMAP,
			ErrMsg: "成长路线图不存在",
		}, nil
	}
	//只有路线图owner可以修改
	if roadmapItem.OwnerUserId != sessItem.UserId {
		return &roadmap_data_api.UpdateEdgeResponse{
			Code:   roadmap_data_api.UpdateEdgeResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	exist, err := roadmap_dao.EdgeInfoDao.Exist(ctx, req.RoadmapId, &roadmap_dao.EdgeKeyDbItem{
		FromNodeId: req.EdgeKey.FromNodeId,
		FromHandle: req.EdgeKey.FromHandle,
		ToNodeId:   req.EdgeKey.ToNodeId,
		ToHandle:   req.EdgeKey.ToHandle,
	})
	if err != nil {
		return nil, err
	}
	if !exist {
		return &roadmap_data_api.UpdateEdgeResponse{
			Code:   roadmap_data_api.UpdateEdgeResponse_CODE_NO_EDGE,
			ErrMsg: "成长路线图连接不存在",
		}, nil
	}

	nowTime := time.Now().UnixMilli()

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx context.Context) (interface{}, error) {
		err = roadmap_dao.EdgeInfoDao.UpdateBasic(sessCtx, req.RoadmapId,
			&roadmap_dao.EdgeKeyDbItem{
				FromNodeId: req.EdgeKey.FromNodeId,
				FromHandle: req.EdgeKey.FromHandle,
				ToNodeId:   req.EdgeKey.ToNodeId,
				ToHandle:   req.EdgeKey.ToHandle,
			},
			&roadmap_dao.BasicEdgeInfoDbItem{
				EdgeType:      req.BasicInfo.EdgeType,
				HasStartArrow: req.BasicInfo.HasStartArrow,
				HasEndArrow:   req.BasicInfo.HasEndArrow,
				Label:         req.BasicInfo.Label,
			}, nowTime)
		if err != nil {
			return nil, err
		}
		return &roadmap_data_api.UpdateEdgeResponse{
			Code: roadmap_data_api.UpdateEdgeResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*roadmap_data_api.UpdateEdgeResponse), nil
}

func (apiImpl *RoadmapDataApiImpl) RemoveEdge(ctx context.Context, req *roadmap_data_api.RemoveEdgeRequest) (*roadmap_data_api.RemoveEdgeResponse, error) {
	sessItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &roadmap_data_api.RemoveEdgeResponse{
			Code:   roadmap_data_api.RemoveEdgeResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	//获取路线图信息
	roadmapItem, err := roadmap_dao.RoadmapInfoDao.Get(ctx, req.RoadmapId)
	if err != nil {
		return &roadmap_data_api.RemoveEdgeResponse{
			Code:   roadmap_data_api.RemoveEdgeResponse_CODE_NO_ROADMAP,
			ErrMsg: "成长路线图不存在",
		}, nil
	}
	//只有路线图owner可以修改
	if roadmapItem.OwnerUserId != sessItem.UserId {
		return &roadmap_data_api.RemoveEdgeResponse{
			Code:   roadmap_data_api.RemoveEdgeResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	exist, err := roadmap_dao.EdgeInfoDao.Exist(ctx, req.RoadmapId, &roadmap_dao.EdgeKeyDbItem{
		FromNodeId: req.EdgeKey.FromNodeId,
		FromHandle: req.EdgeKey.FromHandle,
		ToNodeId:   req.EdgeKey.ToNodeId,
		ToHandle:   req.EdgeKey.ToHandle,
	})
	if err != nil {
		return nil, err
	}
	if !exist {
		return &roadmap_data_api.RemoveEdgeResponse{
			Code: roadmap_data_api.RemoveEdgeResponse_CODE_OK,
		}, nil
	}

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx context.Context) (interface{}, error) {
		err = roadmap_dao.EdgeInfoDao.Remove(sessCtx, req.RoadmapId, &roadmap_dao.EdgeKeyDbItem{
			FromNodeId: req.EdgeKey.FromNodeId,
			FromHandle: req.EdgeKey.FromHandle,
			ToNodeId:   req.EdgeKey.ToNodeId,
			ToHandle:   req.EdgeKey.ToHandle,
		})
		if err != nil {
			return nil, err
		}
		return &roadmap_data_api.RemoveEdgeResponse{
			Code: roadmap_data_api.RemoveEdgeResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*roadmap_data_api.RemoveEdgeResponse), nil
}

func (apiImpl *RoadmapDataApiImpl) ListEdge(ctx context.Context, req *roadmap_data_api.ListEdgeRequest) (*roadmap_data_api.ListEdgeResponse, error) {
	emptyList := []*roadmap_data_api.EdgeInfo{}

	sessItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &roadmap_data_api.ListEdgeResponse{
			Code:     roadmap_data_api.ListEdgeResponse_CODE_WRONG_SESSION,
			ErrMsg:   "会话不存在",
			EdgeList: emptyList,
		}, nil
	}
	//获取路线图信息
	roadmapItem, err := roadmap_dao.RoadmapInfoDao.Get(ctx, req.RoadmapId)
	if err != nil {
		return &roadmap_data_api.ListEdgeResponse{
			Code:     roadmap_data_api.ListEdgeResponse_CODE_NO_ROADMAP,
			ErrMsg:   "成长路线图不存在",
			EdgeList: emptyList,
		}, nil
	}
	//只有路线图owner和路线图成员可以访问
	if roadmapItem.OwnerUserId != sessItem.UserId {
		exist, err := roadmap_dao.RoadmapMemberDao.Exist(ctx, req.RoadmapId, sessItem.UserId)
		if err != nil {
			return nil, err
		}
		if !exist {
			return &roadmap_data_api.ListEdgeResponse{
				Code:     roadmap_data_api.ListEdgeResponse_CODE_NO_PERMISSION,
				ErrMsg:   "没有权限",
				EdgeList: emptyList,
			}, nil
		}
	}

	edgeItemList, err := roadmap_dao.EdgeInfoDao.List(ctx, req.RoadmapId)
	if err != nil {
		return nil, err
	}
	edgeList := []*roadmap_data_api.EdgeInfo{}
	for _, edgeItem := range edgeItemList {
		edgeList = append(edgeList, edgeItem.ToEdgeInfo())
	}
	return &roadmap_data_api.ListEdgeResponse{
		Code:     roadmap_data_api.ListEdgeResponse_CODE_OK,
		EdgeList: edgeList,
	}, nil
}

func (apiImpl *RoadmapDataApiImpl) GetEdge(ctx context.Context, req *roadmap_data_api.GetEdgeRequest) (*roadmap_data_api.GetEdgeResponse, error) {
	emptyInfo := &roadmap_data_api.EdgeInfo{
		EdgeKey:   &roadmap_data_api.EdgeKey{},
		BasicInfo: &roadmap_data_api.BasicEdgeInfo{},
	}

	sessItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &roadmap_data_api.GetEdgeResponse{
			Code:   roadmap_data_api.GetEdgeResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
			Edge:   emptyInfo,
		}, nil
	}
	//获取路线图信息
	roadmapItem, err := roadmap_dao.RoadmapInfoDao.Get(ctx, req.RoadmapId)
	if err != nil {
		return &roadmap_data_api.GetEdgeResponse{
			Code:   roadmap_data_api.GetEdgeResponse_CODE_NO_ROADMAP,
			ErrMsg: "成长路线图不存在",
			Edge:   emptyInfo,
		}, nil
	}
	//只有路线图owner和路线图成员可以访问
	if roadmapItem.OwnerUserId != sessItem.UserId {
		exist, err := roadmap_dao.RoadmapMemberDao.Exist(ctx, req.RoadmapId, sessItem.UserId)
		if err != nil {
			return nil, err
		}
		if !exist {
			return &roadmap_data_api.GetEdgeResponse{
				Code:   roadmap_data_api.GetEdgeResponse_CODE_NO_PERMISSION,
				ErrMsg: "没有权限",
				Edge:   emptyInfo,
			}, nil
		}
	}

	edgeItem, err := roadmap_dao.EdgeInfoDao.Get(ctx, req.RoadmapId, &roadmap_dao.EdgeKeyDbItem{
		FromNodeId: req.EdgeKey.FromNodeId,
		FromHandle: req.EdgeKey.FromHandle,
		ToNodeId:   req.EdgeKey.ToNodeId,
		ToHandle:   req.EdgeKey.ToHandle,
	})
	if err != nil {
		return &roadmap_data_api.GetEdgeResponse{
			Code:   roadmap_data_api.GetEdgeResponse_CODE_NO_EDGE,
			ErrMsg: "成长路线图连接不存在",
			Edge:   emptyInfo,
		}, nil
	}
	return &roadmap_data_api.GetEdgeResponse{
		Code: roadmap_data_api.GetEdgeResponse_CODE_OK,
		Edge: edgeItem.ToEdgeInfo(),
	}, nil
}
